#include "../base/types.h"
#include "../base/logger.h"
#include <chrono>
#include <functional>


OPEN_JLIB_NS


struct SteadyTimer {

  typedef std::chrono::steady_clock::time_point time_point_t;
  typedef std::chrono::duration<double, std::ratio<1, 1>> duration_t;
  typedef std::function<void(double)> callback_t;


  inline double duration () noexcept {
    auto now = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<duration_t>(now - _start + _elapsed);
    return duration.count();
  }


  inline void restart () noexcept {
    _elapsed = time_point_t::duration(0);
    _start = std::chrono::steady_clock::now();
  }

  inline void pause () noexcept {
    _elapsed += std::chrono::steady_clock::now() - _start;
  }

  inline void resume () noexcept {
    _start = std::chrono::steady_clock::now();
  }


  inline SteadyTimer () noexcept {
  }

  inline SteadyTimer (callback_t&& callback) noexcept {
    restart();
    _callback = std::move(callback);
  }

  inline ~SteadyTimer () noexcept {
    if (!_callback)
      return;
    auto end = std::chrono::steady_clock::now();
    auto duration = std::chrono::duration_cast<duration_t>(end - _start);
    _callback(duration.count());
  }


private:
  time_point_t::duration _elapsed;
  time_point_t _start;
  callback_t _callback;
};


CLOSE_JLIB_NS


